From 1db53b83952ee070d9b951050eec9c3bfc08b769 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 28 Jun 2014 16:55:02 -0700 Subject: [PATCH] Make CargoError inherit from Send Due to a bug in the compiler, this also requires adding `+ Send` any time that CargoError is mentioned. This change will allow errors to be sent across tasks. --- src/cargo/core/package_id.rs | 7 ++- src/cargo/util/errors.rs | 86 ++++++++++++++++++------------------ src/cargo/util/result.rs | 12 ++--- 3 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/cargo/core/package_id.rs b/src/cargo/core/package_id.rs index 719c709a5..1a421fe63 100644 --- a/src/cargo/core/package_id.rs +++ b/src/cargo/core/package_id.rs @@ -115,8 +115,11 @@ impl Show for PackageId { } } -impl>> Decodable> for PackageId { - fn decode(d: &mut D) -> Result> { +impl>> + Decodable> + for PackageId +{ + fn decode(d: &mut D) -> Result> { let vector: Vec = match Decodable::decode(d) { Ok(v) => v, Err(e) => return Err(e.to_error()) diff --git a/src/cargo/util/errors.rs b/src/cargo/util/errors.rs index 09035efce..e67f9c0cf 100644 --- a/src/cargo/util/errors.rs +++ b/src/cargo/util/errors.rs @@ -6,39 +6,39 @@ use std::str; use TomlError = toml::Error; -pub trait CargoError { +pub trait CargoError: Send { fn description(&self) -> String; fn detail(&self) -> Option { None } - fn cause<'a>(&'a self) -> Option<&'a CargoError> { None } + fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> { None } fn is_human(&self) -> bool { false } fn to_error>(self) -> E { FromError::from_error(self) } - fn box_error(self) -> Box { - box self as Box + fn box_error(self) -> Box { + box self as Box } fn concrete(&self) -> ConcreteCargoError { ConcreteCargoError { description: self.description(), detail: self.detail(), - cause: self.cause().map(|c| box c.concrete() as Box), + cause: self.cause().map(|c| box c.concrete() as Box), is_human: self.is_human() } } - fn with_cause(self, cause: E) -> Box { + fn with_cause(self, cause: E) -> Box { let mut concrete = self.concrete(); concrete.cause = Some(cause.box_error()); - box concrete as Box + box concrete as Box } - fn mark_human(self) -> Box { + fn mark_human(self) -> Box { let mut concrete = self.concrete(); concrete.is_human = true; - box concrete as Box + box concrete as Box } } @@ -46,8 +46,8 @@ pub trait FromError { fn from_error(error: E) -> Self; } -impl FromError for Box { - fn from_error(error: E) -> Box { +impl FromError for Box { + fn from_error(error: E) -> Box { error.box_error() } } @@ -69,7 +69,7 @@ impl Show for Box { } } -impl CargoError for Box { +impl CargoError for Box { fn description(&self) -> String { (*self).description() } @@ -78,7 +78,7 @@ impl CargoError for Box { (*self).detail() } - fn cause<'a>(&'a self) -> Option<&'a CargoError> { + fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> { (*self).cause() } @@ -86,35 +86,35 @@ impl CargoError for Box { (*self).is_human() } - fn box_error(self) -> Box { + fn box_error(self) -> Box { self } } -pub type CargoResult = Result>; +pub type CargoResult = Result>; pub trait BoxError { fn box_error(self) -> CargoResult; } pub trait ChainError { - fn chain_error(self, callback: || -> E) -> CargoResult ; + fn chain_error(self, callback: || -> E) -> CargoResult ; } impl<'a, T> ChainError for ||:'a -> CargoResult { - fn chain_error(self, callback: || -> E) -> CargoResult { + fn chain_error(self, callback: || -> E) -> CargoResult { self().map_err(|err| callback().with_cause(err)) } } -impl BoxError for Result { +impl BoxError for Result { fn box_error(self) -> CargoResult { self.map_err(|err| err.box_error()) } } -impl ChainError for Result { - fn chain_error(self, callback: || -> E) -> CargoResult { +impl ChainError for Result { + fn chain_error(self, callback: || -> E) -> CargoResult { self.map_err(|err| callback().with_cause(err)) } } @@ -144,7 +144,7 @@ pub struct ProcessError { pub exit: Option, pub output: Option, pub detail: Option, - pub cause: Option> + pub cause: Option> } from_error!(ProcessError) @@ -184,20 +184,21 @@ impl CargoError for ProcessError { self.detail.clone() } - fn cause<'a>(&'a self) -> Option<&'a CargoError> { - self.cause.as_ref().map(|c| { let err: &CargoError = *c; err }) + fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> { + self.cause.as_ref().map(|c| { let err: &CargoError + Send = *c; err }) } - fn with_cause(mut self, err: E) -> Box { + fn with_cause(mut self, + err: E) -> Box { self.cause = Some(err.box_error()); - box self as Box + box self as Box } } pub struct ConcreteCargoError { description: String, detail: Option, - cause: Option>, + cause: Option>, is_human: bool } @@ -216,18 +217,19 @@ impl CargoError for ConcreteCargoError { self.detail.clone() } - fn cause<'a>(&'a self) -> Option<&'a CargoError> { - self.cause.as_ref().map(|c| { let err: &CargoError = *c; err }) + fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> { + self.cause.as_ref().map(|c| { let err: &CargoError + Send = *c; err }) } - fn with_cause(mut self, err: E) -> Box { + fn with_cause(mut self, + err: E) -> Box { self.cause = Some(err.box_error()); - box self as Box + box self as Box } - fn mark_human(mut self) -> Box { + fn mark_human(mut self) -> Box { self.is_human = true; - box self as Box + box self as Box } fn is_human(&self) -> bool { @@ -239,7 +241,7 @@ pub type CliResult = Result; #[deriving(Show)] pub struct CliError { - pub error: Box, + pub error: Box, pub unknown: bool, pub exit_code: uint } @@ -259,11 +261,11 @@ impl CliError { } pub fn from_error(error: E, code: uint) -> CliError { - let error = box error as Box; + let error = box error as Box; CliError::from_boxed(error, code) } - pub fn from_boxed(error: Box, code: uint) -> CliError { + pub fn from_boxed(error: Box, code: uint) -> CliError { let human = error.is_human(); CliError { error: error, exit_code: code, unknown: !human } } @@ -278,34 +280,34 @@ pub fn process_error(msg: S, exit: status.map(|o| o.clone()), output: output.map(|o| o.clone()), detail: None, - cause: cause.map(|c| box c as Box) + cause: cause.map(|c| box c as Box) } } pub fn internal_error(error: S1, - detail: S2) -> Box { + detail: S2) -> Box { box ConcreteCargoError { description: error.as_slice().to_str(), detail: Some(detail.as_slice().to_str()), cause: None, is_human: false - } as Box + } as Box } -pub fn internal(error: S) -> Box { +pub fn internal(error: S) -> Box { box ConcreteCargoError { description: error.to_str(), detail: None, cause: None, is_human: false - } as Box + } as Box } -pub fn human(error: S) -> Box { +pub fn human(error: S) -> Box { box ConcreteCargoError { description: error.to_str(), detail: None, cause: None, is_human: true - } as Box + } as Box } diff --git a/src/cargo/util/result.rs b/src/cargo/util/result.rs index d47ca51e8..108e08488 100644 --- a/src/cargo/util/result.rs +++ b/src/cargo/util/result.rs @@ -1,11 +1,11 @@ use util::errors::{CargoResult, CargoError}; pub trait Wrap { - fn wrap(self, error: E) -> Self; + fn wrap(self, error: E) -> Self; } -impl Wrap for Result> { - fn wrap(self, error: E) -> CargoResult { +impl Wrap for Result> { + fn wrap(self, error: E) -> CargoResult { match self { Ok(x) => Ok(x), Err(e) => Err(error.with_cause(e)) @@ -14,14 +14,14 @@ impl Wrap for Result> { } pub trait Require { - fn require(self, err: || -> E) -> CargoResult; + fn require(self, err: || -> E) -> CargoResult; } impl Require for Option { - fn require(self, err: || -> E) -> CargoResult { + fn require(self, err: || -> E) -> CargoResult { match self { Some(x) => Ok(x), - None => Err(box err().concrete() as Box) + None => Err(box err().concrete() as Box) } } } -- 2.30.2